package util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xalan.internal.xsltc.trax.DOM2SAX;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.xml.sax.SAXException;
import play.Play;
import play.libs.XPath;
import play.mvc.Http;
import scala.xml.Node;
import scala.xml.parsing.NoBindingFactoryAdapter;

import javax.swing.text.Document;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Created by Administrator on 2016/2/24.
 */
public class Common {

    public static String encode(String algorithm, String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }


    public static String sha1(String s) {
        if (s == null) {
            return null;
        }
        return encode("SHA1", s);
    }

    public static String randomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public static String randomStringForNum(int length) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }


    public static String md5(String str) {
        try {
            byte[] bytesOfMessage = str.getBytes("UTF-8");
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] thedigest = md.digest(bytesOfMessage);
            return new String(thedigest, Charset.forName("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            return str;
        } catch (UnsupportedEncodingException e2) {
            return str;
        }
    }

    public static String md5(String str, int digit){
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes("utf-8"));
            //获得密文
            byte b[] = md.digest();

            // 把密文转换成十六进制的字符串形式
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            if (digit == 16) {
                return buf.toString().substring(8, 24);
            } else if (digit == 32) {
                return buf.toString();
            }

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String md5(File file) throws FileNotFoundException {
        String value = null;
        FileInputStream in = new FileInputStream(file);
        try {
            MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(byteBuffer);
            BigInteger bi = new BigInteger(1, md5.digest());
            value = bi.toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return value;
    }


    public static String base64encode(String str) {
        try {
            return new String(Base64.encodeBase64(str.getBytes("UTF-8")));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getStringConfig(String key) {
        return Play.application().configuration().getString(key);
    }
    public static String getStringConfig(String key, String defaultValue) {
        return Play.application().configuration().getString(key, defaultValue);
    }
    public static boolean getBooleanConfig(String key) {
        return Play.application().configuration().getBoolean(key);
    }
    public static int getIntConfig(String key) {
        return getIntConfig(key, 0);
    }
    public static int getIntConfig(String key, int defaultValue) {
        play.Configuration configuration = Play.application().configuration();
        if (!configuration.keys().contains(key)) {
            return defaultValue;
        }
        return Play.application().configuration().getInt(key);
    }
    //获取play项目中conf文件下的文件流
    public static InputStream getResource(String path) {
        return Play.application().classloader().getResourceAsStream(path);
    }

    //设置对象属性值
    public static void setPropertyOfObject(Object obj, String name, Object val) {
        Class cls = obj.getClass();
        Field field = null;
        try {
            field = cls.getField(name);
            field.setAccessible(true);
            field.set(obj, val);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取对象的名为name的属性，使用反射。如果不存在，则返回null
     */
    public static Object getPropertyOfObject(Object obj, String name) {
        if (obj == null) {
            return null;
        }
        Class cls = obj.getClass();
        try {
            Field field = cls.getField(name);
            field.setAccessible(true);
            return field.get(obj);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }


    //获取对象中的所有属性
    public static List<Field> getFields(Object obj) {
        if (obj == null) {
            return null;
        }
        Class cls = obj.getClass();
        List<Field> result = new ArrayList<Field>();
        for (Field field : cls.getFields()) {
            result.add(field);
        }
        return result;
    }

    //设置类object中属性field值为value
    public static void setValueOfObjecProperty(Object obj, Field field,String value) {
        Object val = null;
        Class type = field.getType();
        if (type == String.class) {
            val =  value;
        } else if (type == Integer.class || type == int.class) {
            val =  Integer.valueOf(value);
        } else if (type == Long.class || type == long.class) {
            val =  Long.valueOf(value);
        } else if (type == Float.class || type == float.class) {
            val =  Float.valueOf(value);
        } else if (type == Double.class || type == double.class) {
            val =  Double.valueOf(value);
        }
        Common.setPropertyOfObject(obj, field.getName(), val);
    }


}
